﻿using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using EntityFrameworkETL.Interfaces;
using System.Data.Common;
using System.Collections.Generic;
using System.Data.SqlClient;
using EntityFrameworkETL.Test.Mocks;

namespace EntityFrameworkETL.Test
{
    [TestClass]
    public class ExecuteBatchCommandsTest
    {
        private ExecuteNonQueryMock ExecuteNonQueryMock { get; set; }
        private BatchAndExecuteCommands BatchAndExecuteCommands { get; set; }
        private List<DbCommand> Commands { get; set; }

        [TestInitialize]
        public void TestInitialize()
        {
            ExecuteNonQueryMock = new ExecuteNonQueryMock();
            BatchAndExecuteCommands = new BatchAndExecuteCommands("", ExecuteNonQueryMock);
            Commands = new List<DbCommand>();
        }

        [TestMethod]
        public void Execute_WithOneCommand_ExecutesOneCommands()
        {
            Commands.Add(new SqlCommand());

            BatchAndExecuteCommands.Execute(Commands);

            Assert.IsTrue(ExecuteNonQueryMock.CallCount == 1);
        }

        [TestMethod]
        public void Execute_With100Commands_ExecutesOnce()
        {
            for (int i = 0; i < 100; i++)
            {
                var command = new SqlCommand();
                Commands.Add(command);    
            }

            BatchAndExecuteCommands.Execute(Commands);

            Assert.IsTrue(ExecuteNonQueryMock.CallCount == 1);
        }

        [TestMethod]
        public void Execute_With1000Commands_ExecutesOnce()
        {
            for (int i = 0; i < 1000; i++)
            {
                var command = new SqlCommand();
                Commands.Add(command);
            }

            BatchAndExecuteCommands.Execute(Commands);

            Assert.IsTrue(ExecuteNonQueryMock.CallCount == 1);
        }

        [TestMethod]
        public void Execute_With3000Parameters_ExecutesTwice()
        {
            for (int i = 0; i < 1000; i++)
            {
                var command = new SqlCommand();
                command.Parameters.Add(new SqlParameter("", ""));
                command.Parameters.Add(new SqlParameter("", ""));
                command.Parameters.Add(new SqlParameter("", ""));
                Commands.Add(command);
            }

            BatchAndExecuteCommands.Execute(Commands);

            Assert.IsTrue(ExecuteNonQueryMock.CallCount == 2);
        }

        [TestMethod]
        public void Execute_With5000Parameters_ExecutesThreeTimes()
        {
            for (int i = 0; i < 1000; i++)
            {
                var command = new SqlCommand();
                command.Parameters.Add(new SqlParameter("", ""));
                command.Parameters.Add(new SqlParameter("", ""));
                command.Parameters.Add(new SqlParameter("", ""));
                command.Parameters.Add(new SqlParameter("", ""));
                command.Parameters.Add(new SqlParameter("", ""));
                Commands.Add(command);
            }

            BatchAndExecuteCommands.Execute(Commands);

            Assert.IsTrue(ExecuteNonQueryMock.CallCount == 3);
        }
    }
}
